import requests
import json
from colorama import Fore

class LogBean(object):
    error_logs = []
    info_logs = []
    full_log = ''


class RequestCounterBean(object):
    success = 0
    error = 0
    run = 0


class RequestDetailsBean(object):
    login_url = 'http://localhost:8089/webecg/login?username=dHMwMDE&password=dHMwMDE'
    request_url = None
    headers = None
    method_type = None
    param = None


class ResponseDetailsBean(object):
    response_body = []


class AbstractMockHttp:
    request_details = None
    request_counter = RequestCounterBean()
    log = LogBean()
    response_details = None

    def init_headers(self):
        try:
            cookies = requests.post(self.request_details.login_url).cookies.items()
        except BaseException as e:
            self.log.full_log += '\n %s' % e

        cookie_str = ''
        for ck in cookies:
            cookie_str += '%s=%s;'%(ck[0],ck[1])
        headers = {
            "Accept": "*/*",
            "Accept-Encoding": "gzip, deflate, br",
            "Accept-Language": "zh-Hans-CN,zh-Hans;q=0.8,en-US;q=0.5,en;q=0.3",
            "Connection": "keep-alive",
            "Content-Type": "application/json",
            "User-Agent": "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; Tablet PC 2.0; wbx 1.0.0; wbxapp 1.0.0; Zoom 3.6.0)",
            "Cookie": cookie_str
        }
        # cookies[0][0] + "=" + cookies[0][1]
        self.request_details.headers = headers

    def post_request(self, param):
        try:
            if (self.request_details.headers == None):
                self.init_headers()

            if (param == None):
                try:
                    self.log.full_log += "\n 第 %d 次post请求head 为\n[%s] " % (
                        self.request_counter.run + 1, json.dumps(sort_keys=True, indent=4, separators=(',', ':'), ensure_ascii=False,obj=self.request_details.headers))
                    response = requests.post(url=self.request_details.request_url,
                                             headers=self.request_details.headers).text
                except BaseException as e:
                    self.log.full_log += '\n %s' % e
            else:
                json_data = json.dumps(param)
                # print(Fore.BLUE +"第 %d 次post请求 入参为 \n %s" % (
                #     self.request_index,
                #     json.dumps(sort_keys=True, indent=4, separators=(',', ':'), ensure_ascii=False, obj=self.param)))
                self.log.full_log += "\n 第 %d 次post请求head 为\n[%s] \n入参为 \n %s" % (
                    self.request_counter.run+1,json.dumps(sort_keys=True, indent=4, separators=(',', ':'), ensure_ascii=False,obj=self.request_details.headers),
                    json.dumps(sort_keys=True, indent=4, separators=(',', ':'), ensure_ascii=False,
                               obj=self.request_details.param))
                response = requests.post(url=self.request_details.request_url, headers=self.request_details.headers,
                                         data=json_data).text

            # 校验1 state 必须为1
            rs = json.loads(response)
            # print(Fore.GREEN + "输出结果为 ： \n %s " % (
            #     json.dumps(sort_keys=True, indent=4, separators=(',', ':'), ensure_ascii=False, obj=rs)))
            self.log.full_log += "\n 第 %d 次输出结果为 ： \n %s " % (
                self.request_counter.run+1,
                json.dumps(sort_keys=True, indent=4, separators=(',', ':'), ensure_ascii=False, obj=rs))
            if (rs["state"] != "1"):
                self.request_counter.error += 1
                error_info = {
                    "request_url": self.request_details.request_url,
                    "response": rs
                }
                self.log.error_logs.append(
                    json.dumps(sort_keys=True, indent=4, separators=(',', ':'), ensure_ascii=False, obj=error_info))
            else:
                return rs
        except BaseException as e:
            self.request_counter.error += 1
            error_info = {
                "request_url": self.request_details.request_url,
                "response": rs
            }
            self.log.error_logs.append(
                json.dumps(sort_keys=True, indent=4, separators=(',', ':'), ensure_ascii=False, obj=error_info))
        finally:
            self.request_counter.run += 1

    def go_post(self):

        if (self.request_details.param != None):
            for i in self.request_details.param:
                self.response_details.response_body.append(self.post_request(i))
        else:
            self.response_details.response_body.append(self.post_request(None))


class RequestHD(AbstractMockHttp):
    validate_attributes = None

    validate_error_log = ""

    validate_attribute_name = 'results'

    nonExist_attribute = []

    def __init__(self, paths=[]):
        for path in paths:
            request_obj = json.load(open(path, 'r', encoding='utf-8'))
            request_details = RequestDetailsBean()
            if "login_url" in request_obj:
                request_details.login_url = request_obj["login_url"]

            if "request_url" in request_obj:
                request_details.request_url = request_obj["request_url"]
            else:
                self.log.error_logs.append("%d 文件的 request_url 属性必填" % path)

            if "param" in request_obj:
                request_details.param = request_obj["param"]

            if "validate_attributes" in request_obj:
                self.validate_attributes = request_obj["validate_attributes"]

            if "validate_attribute_name" in request_obj:
                self.validate_attribute_name = request_obj["validate_attribute_name"]

            self.request_details = request_details
            self.response_details = ResponseDetailsBean()
            self.handle()
            self.clear_request_cache()

    def clear_request_cache(self):
        self.request_details = None
        self.response_details = None
        self.validate_attributes = None

    def dict_cmp(self, origin, new):
        for i in origin:
            if (i not in new):
                self.nonExist_attribute.append(i)
                return False

        return True

    def check_attribute(self, datas):
        for i in datas:
            if (isinstance(i, dict)):
                rs = i.get(self.validate_attribute_name)
                if isinstance(rs,list):
                    for r in rs:
                        attrs = r.keys()
                        if (not self.dict_cmp(self.validate_attributes, attrs)):
                            self.validate_error_log += "%s 请求参数校验失败,不存在的参数%s"%(self.request_details.request_url,self.nonExist_attribute)
                            self.request_counter.error+=1
                            return
                else:
                    attrs = i.keys()
                    if (not self.dict_cmp(self.validate_attributes, attrs)):
                        self.validate_error_log += "%s 请求参数校验失败,不存在的参数%s" % (self.request_details.request_url,self.nonExist_attribute)
                        self.request_counter.error += 1
                        return



    def handle(self):
        self.go_post()
        if ((self.validate_attributes != None) and len(self.validate_attributes) > 0):
            self.check_attribute(datas=self.response_details.response_body)

    def get_log(self):
        # print(Fore.YELLOW + "本次测试共%d 次,成功%d次,失败 %d 次 失败信息如下: " % (
        #     self.request_counter.run, self.request_counter.success, self.request_counter.error))
        self.log.full_log += "\n 本次测试共%d 次,成功%d次,失败 %d 次 " % (
            self.request_counter.run, self.request_counter.run-self.request_counter.error, self.request_counter.error)
        if len(self.log.error_logs)>0:
            self.log.full_log += "\n 失败信息如下: "
            for error in self.log.error_logs:
                print(Fore.RED + error)
                self.log.full_log += "\n"+error
        return self.log.full_log + "\n" + self.validate_error_log

    def console_print(self, check):
        log = self.get_log()
        print(log)
        check.ids['consoleId'].text = log
        check.ids['run'].disabled = False


if __name__ == "__main__":
    rhd = RequestHD(['../../test/traffic工程迁移Ecg测试入参/ListSuanfaserverSetting.json','../../test/traffic工程迁移Ecg测试入参/ListSuanfaserverSetting.json','../../test/traffic工程迁移Ecg测试入参/ListSuanfaserverSetting.json'])
    print(rhd.get_log())
